package com.yjd.api.user;

import com.yjd.comm.bank.model.BankModel;
import com.yjd.comm.bank.service.IBankService;
import com.yjd.comm.base.control.MobileBaseControl;
import com.yjd.comm.base.enums.DbWREnums;
import com.yjd.comm.base.service.IMfqTokenService;
import com.yjd.comm.device.service.IDeviceService;
import com.yjd.comm.enums.ApiRequestWayEnum;
import com.yjd.comm.enums.ReferenceTypeEnum;
import com.yjd.comm.system.util.SysParamUtil;
import com.yjd.comm.user.dto.UserSession;
import com.yjd.comm.user.model.UserDataModel;
import com.yjd.comm.user.model.UserModel;
import com.yjd.comm.user.service.IUserDataService;
import com.yjd.comm.user.service.IUserService;
import com.yjd.comm.user.util.UserUtil;
import com.yjd.comm.util.*;
import com.yjd.comm.vo.Constant;
import com.yjd.comm.zhima.model.ZhimaCreditModel;
import com.yjd.comm.zhima.service.IZhimaCreditService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import javax.annotation.Resource;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 我的首页
 * Created by yjd-wap on 2017/6/28.
 */

@Controller
@Scope("prototype")
@RequestMapping("/myInfo/")
public class MyInfoControl extends MobileBaseControl {
    @Resource
    private IUserService userService;
    @Resource
    private IDeviceService deviceService;

    @Resource
    private IUserDataService userDataService;

    @Resource
    private IBankService bankService;

    @Resource
    private IZhimaCreditService zhimaCreditService;

    @Resource
    private IMfqTokenService mfqTokenService;

    @RequestMapping(value = "index", method = RequestMethod.POST)
    public void index() throws Exception {
        UserSession userSession = super.getUserSession();
        UserModel userModel = userService.getModelById(userSession.getUser_id(), DbWREnums.READ);
        UserDataModel dataModel = userDataService.getModelById(userSession.getUser_id(), DbWREnums.READ);
        BankModel bankModel = bankService.getModelById(userSession.getUser_id(), DbWREnums.READ);
        ZhimaCreditModel zhimaCreditModel = zhimaCreditService.getModelById(userSession.getUser_id(), DbWREnums.READ);
        String img_url = ServletUtil.getFileUrl(userModel.getPortrait_path());
        String limit = SysParamUtil.getValue(Constant.SysParamKeyEnum.CREDIT_LIMIT_MAX);
        String bank_name = bankModel == null ? "" : bankModel.getBank_name();
        String bank_img = bankModel == null ? "" : ServletUtil.getFileUrl(ReferenceTypeEnum.BANK_PICTURE.getPath() + bankModel.getBank_code() + ".png");
        String bankcode = bankModel == null ? "" : UserUtil.disposeBankCardNo(bankModel.getBank_card_number());
        String bank_mobile = bankModel == null ? "" : UserUtil.disposeMobile(bankModel.getBank_mobile().toString());
        String mobile_number = null == userModel.getMobile_number() ? "" : UserUtil.disposeMobile(userModel.getMobile_number().toString());
        String zhima_auth = zhimaCreditModel == null ? "0" : zhimaCreditModel.getStatus() == 0 ? "0" : "1";
        int is_pay = StringUtil.isEmpty(userSession.getPay_password()) ? 0 : 1;
        successData(FrameUtil.newHashMap(
                "mobile", mobile_number,
                "portrait", img_url,
                "credit", NumberUtil.formatNumber(dataModel.getCredit_line()),
                "residual_amount", NumberUtil.formatNumber(dataModel.getResidual_amount()),
                "credit_max", limit,
                "idname", UserUtil.disposeUserName(dataModel.getId_name()),
                "idcard", UserUtil.disposeIdCard(dataModel.getId_number()),
                "bank_name", bank_name,
                "bank_img", bank_img,
                "bankcode", bankcode,
                "bank_mobile", bank_mobile,
                "is_pay", is_pay,
                "zhima_auth", zhima_auth));
    }

    /**
     * 设置交易密码
     *
     * @param password   密码
     * @param pwdConfirm 确认密码
     * @throws Exception
     */
    @RequestMapping(value = "pwd/pay/set", method = RequestMethod.POST)
    public void setPayPwd(@RequestParam(required = false) String password,
                          @RequestParam(required = false) String pwdConfirm)
            throws Exception {
        if (!validate(password, pwdConfirm)) {
            return;
        }

        UserModel uModel = userService.getModelById(super.getUserSession()
                .getUser_id(), DbWREnums.READ);
        if (uModel == null) {
            FrameUtil.throwBaseException1("数据信息异常");
        }

        if (!StringUtil.isEmpty(uModel.getPay_password())) {
            FrameUtil.throwBaseException1("您已经设置交易密码");
        }

        // 是否实名认证
        if (!userService.modifyPayPassword(super.getUserSession().getUser_id(),
                password)) {
            FrameUtil.throwBaseException1("修改交易密码失败");
        }

        super.successMsg("设置交易密码成功");
    }

    /**
     * 修改交易密码
     *
     * @param oldPassword 老密码
     * @param password    密码
     * @param pwdConfirm  确认密码
     * @throws Exception
     */
    @RequestMapping(value = "pwd/pay/change", method = RequestMethod.POST)
    public void changePayPwd(@RequestParam(required = false) String oldPassword, @RequestParam(required = false) String password,
                             @RequestParam(required = false) String pwdConfirm)
            throws Exception {
        if (!validate(password, pwdConfirm)) {
            return;
        }
        UserSession userSession = super.getUserSession();
        String pwdMd5 = SecurityCode.passwordMD5(oldPassword, userSession.getEncrypt());
        if (!pwdMd5.equals(userSession.getPay_password())) {
            FrameUtil.throwBaseException1("原交易密码输入不正确");
        }

        // 是否实名认证
        UserDataModel dataModel = userDataService.getModelById(userSession.getUser_id(), DbWREnums.READ);
        if (dataModel == null || StringUtil.isEmpty(dataModel.getId_name()) || StringUtil.isEmpty(dataModel.getId_number())) {
            FrameUtil.throwBaseException1("您还未实名绑定银行卡");
        }

        if (!userService.modifyPayPassword(super.getUserSession().getUser_id(),
                password)) {
            FrameUtil.throwBaseException1("修改交易密码失败");
        }

        super.successMsg("设置交易密码成功");
    }

    /**
     * 重置交易密码（先验证身份/myInfo/validate/user）
     *
     * @param payPwd 新支付密码
     * @param payPwdConfirm 确认支付密码
     * @param valid_token 验证token
     * @throws Exception
     */
    @RequestMapping(value = "pwd/pay/reset", method = RequestMethod.POST)
    public void resetPayPassword(String payPwd, String payPwdConfirm, String valid_token) throws Exception {
        if (!validate(payPwd, payPwdConfirm)) {
            return;
        }

        UserSession userSession = super.getUserSession();
        if (!mfqTokenService.valDateToken(userSession.getUser_id().toString(), valid_token)) {
            this.errorMsg("请求不合法！");
            return;
        }

        if (!userService.modifyPayPassword(userSession.getUser_id(), payPwd)) {
            this.errorMsg("重置交易密码失败");
            return;
        }

        super.successMsg("重置交易密码成功");
    }

    /**
     * 验证身份
     *
     * @param id_name 姓名
     * @param id_number 身份证号码
     * @param msgCode 短信验证码
     * @throws Exception
     */
    @RequestMapping(value = "validate/user")
    public void validateUser(String id_name, String id_number, String msgCode) throws Exception {
        if (    StringUtil.isEmpty(id_name) ||
                StringUtil.isEmpty(id_number) ||
                StringUtil.isEmpty(msgCode) ) {
            this.errorMsg("请求参数错误");
            return;
        }

        /**
         * 1、获取短信验证码/myInfo/get/msg
         * 2、验证验证码是否正确
         * 3、验证姓名和身份证是否正确
         */
        UserSession userSession = super.getUserSession();
        if (!super.compareMessageCode(userSession.getMobile_number().toString(), msgCode)) {
            this.errorMsg("验证码不正确");
            return;
        }

        BankModel bankModel = bankService.getModelById(userSession.getUser_id(), DbWREnums.READ);
        if(null == bankModel){
            FrameUtil.throwBaseException1("用户未绑卡，无法验证。");
        }

        if(id_name.equals(bankModel.getId_name()) && id_number.equals(bankModel.getId_number())){
            String uuid = UUID.randomUUID().toString();
            mfqTokenService.pushKey(userSession.getUser_id().toString(), uuid);
            this.successData("身份匹配", FrameUtil.newHashMap("valid_token", uuid));
        } else {
            this.errorMsg("身份验证不通过");
        }
    }

    /**
     * 获取短信验证码
     *
     * @throws Exception void
     */
    @RequestMapping("get/msg")
    public void getMessage() throws Exception {
        UserSession session = super.getUserSession();
        if(null != session){
            UserModel uModel = userService.getModelById(session.getUser_id(), DbWREnums.READ);
            if (uModel == null) {
                FrameUtil.throwBaseException1("用户信息异常");
            }
            Long mbNumber = uModel.getMobile_number();
            if (mbNumber == null) {
                super.errorMsg("请先绑定手机");
                return;
            }
            super.sendMessage(mbNumber.toString());
        } else {
            Map<String, Object> paramMap = ServletUtil.getParameterMap(request);
            if(StringUtil.isEmpty(paramMap.get("mobile_number"))){
                super.errorMsg("请输入手机号");
                return;
            }

            String mobile_number = paramMap.get("mobile_number").toString();
            UserModel uModel = userService.getModelOne(FrameUtil.newHashMap("mobile_number", mobile_number), DbWREnums.READ);
            if(null == uModel){
                super.errorMsg("该手机号不存在或未注册");
                return;
            }

            super.sendMessage(mobile_number);
        }
    }

    /**
     * 修改登录密码
     *
     * @param msgCode  短信验证码
     * @param password 新的登录密码
     * @throws Exception
     */
    @RequestMapping(value = "pwd/login/change", method = RequestMethod.POST)
    public void changeLoginPwd(@RequestParam(required = false) String msgCode, @RequestParam(required = false) String password) throws Exception {
        if (StringUtil.isEmpty(msgCode) || StringUtil.isEmpty(password)) {
            FrameUtil.throwBaseException1("请求参数错误");
        }

        UserSession userSession = super.getUserSession();
        if (!super.compareMessageCode(userSession.getMobile_number().toString(), msgCode)) {
            FrameUtil.throwBaseException1("验证码不正确");
        }
        UserModel userModel = new UserModel();
        userModel.setUser_id(userSession.getUser_id());
        userModel.setPassword(SecurityCode.passwordMD5(password, userSession.getEncrypt()));
        if (userService.update(userModel) != 1) {
            super.errorMsg("系统繁忙,请稍后再试");
            return;
        }
        refreshToken(userModel);
    }

    /**
     * 重置登录密码
     *
     * @param msgCode  短信验证码
     * @param password 新的登录密码
     * @throws Exception
     */
    @RequestMapping(value = "pwd/login/reset", method = RequestMethod.POST)
    public void resetLoginPwd(String mobile_number, String msgCode, String password) throws Exception {
        if (StringUtil.isEmpty(msgCode) || StringUtil.isEmpty(password)) {
            FrameUtil.throwBaseException1("请求参数错误");
        }

        if (!super.compareMessageCode(mobile_number, msgCode)) {
            FrameUtil.throwBaseException1("验证码不正确");
        }

        UserModel uModel = userService.getModelOne(FrameUtil.newHashMap("mobile_number", mobile_number), DbWREnums.READ);
        if(null == uModel){
            super.errorMsg("该手机号不存在或未注册");
            return;
        }

        UserModel userModel = new UserModel();
        userModel.setUser_id(uModel.getUser_id());
        userModel.setPassword(SecurityCode.passwordMD5(password, uModel.getEncrypt()));
        if (userService.update(userModel) != 1) {
            super.errorMsg("系统繁忙,请稍后再试");
            return;
        }

        refreshToken(userModel);
    }

    /**
     * 刷新客户端token
     *
     * @param uModel
     * @throws Exception void
     */
    private void refreshToken(UserModel uModel) throws Exception {
        Long idUser = uModel.getUser_id();
        // 查询用户详细信息
        UserSession mUser = deviceService.getMobileUser(idUser);
        if (mUser == null) {
            this.errorMsg("系统繁忙,请稍后再试");
            return;
        }
        // 生成token
        String token = UserAccessTokenUtil.generateAccessToken(mUser, ApiRequestWayEnum.APP);
        String img_url = ServletUtil.getFileUrl(mUser.getPortrait_path());

        this.successData(FrameUtil.newHashMap("access_token", token, "user_id", mUser.getUser_id(), "idname",
                mUser.getIdname(), "mobile", mUser.getMobile_number(), "img_url", img_url));
    }

    /**
     * 密码校验
     *
     * @param password  密码
     * @param pwdConfim 确认密码
     * @return
     * @throws Exception
     */
    private boolean validate(String password, String pwdConfim)
            throws Exception {
        if (StringUtils.isBlank(password) || StringUtils.isBlank(pwdConfim)) {
            FrameUtil.throwBaseException1("参数异常");
        }
        if (!password.equals(pwdConfim)) {
            this.errorMsg(null, "两次密码输入不相等!");
            return false;
        }
        // 密码不能是中文
        Matcher m = Pattern.compile("[\u4e00-\u9fa5]").matcher(password);
        if (m.matches()) {
            super.errorMsg(null, "交易密码格式不正确哟!");
            return false;
        }
        return true;
    }
}
